package io.gitee.zhangbinhub.acp.boot.listener

import io.gitee.zhangbinhub.acp.core.common.interfaces.IDaemonService
import io.gitee.zhangbinhub.acp.core.common.log.LogFactory
import io.gitee.zhangbinhub.acp.core.common.task.threadpool.ThreadPoolService
import org.noear.solon.core.event.AppStopEndEvent
import org.noear.solon.core.event.EventListener
import java.util.concurrent.ConcurrentLinkedDeque

/**
 * @since JDK 17
 */
class AcpApplicationStopListener : EventListener<AppStopEndEvent> {
    override fun onEvent(event: AppStopEndEvent?) {
        stopAllService()
    }

    companion object {
        private val log = LogFactory.getInstance(AcpApplicationStopListener::class.java)
        private val serverDeque = ConcurrentLinkedDeque<IDaemonService>()

        /**
         * 添加后台守护服务
         *
         * @param daemonService 后台守护服务
         */
        @JvmStatic
        fun addService(daemonService: IDaemonService) {
            synchronized(serverDeque) {
                if (!serverDeque.contains(daemonService)) {
                    serverDeque.push(daemonService)
                    log.info("add daemon service [" + daemonService.getServiceName() + "]")
                }
            }
        }

        @JvmStatic
        fun addAllService(daemonServiceList: List<IDaemonService>) {
            synchronized(serverDeque) {
                daemonServiceList.forEach { daemonService ->
                    run {
                        if (!serverDeque.contains(daemonService)) {
                            serverDeque.push(daemonService)
                            log.info("add daemon service [" + daemonService.getServiceName() + "]")
                        }
                    }
                }
            }
        }

        /**
         * 停止后台守护服务
         */
        @JvmStatic
        fun stopAllService() {
            ThreadPoolService.destroyAll()
            synchronized(serverDeque) {
                while (!serverDeque.isEmpty()) {
                    val daemonService = serverDeque.pop()
                    daemonService.stopService()
                    log.info("destroy daemon service [" + daemonService.getServiceName() + "]")
                }
            }
        }
    }
}
